----------------------------------
STUFF TO TAKE NOTE OF IN MILKSHAPE
----------------------------------


______________________________________________________
RDZ's Algorithm For (Bipedal) Walk Animations at 24fps

Make the first keyframe the model with one foot forward.
TEN frames later, have a keyframe with the other foot forward.
TEN frames later again, have the first keyframe copied in.
Now, the model will slide its feet across, possibly underground, to approximate walking. To add extra realism, make sure not just the feet are changing position; lift the hips a bit, add some sway into the upper body etc.
Between the first foot forward and the second, lift up the foot that is moving forward by rotating etc the knees and hips, the knee will be brought forward a bit, and the foot should be in 'mid air.' Also twist the body a little; when one foot is in the air, you move *slightly* the other way for balance. Remember, its the little things that count. Now do the same for the second phase, the other foot going back and the first foot forward again - lift up the 'moving' foot and tip the body a little. Also, when you're lifting one foot, lift the pelvis a bit too, to get a kind of 'bounce' into the walk. It makes it look more like its moving, and hides the fact that some other bones may not be moving; it makes it seem like the entire model is in motion, like a person is in real life.
The animation should last 20 frames - just less than a second. For use in-game, set Art - Animation Walk Speed to around 150 for a unit that moves at around 270.
___________________________________
WHEN EXPORTED ROTATION SCREWS UP...

Move all the parent bones and thus the skewed bone back to zero position, and work out the skewed bone's rotation from there. Then, take the un-skewed keyframes and paste them into the actual animation sequence. Results should look similar, but the rotation will work in-game.
______________________
GENERAL ANIMATION TIPS

No matter what type of animation is being made, try to make sure AS MUCH AS POSSIBLE of the model is moving. In stand animations, for example; when a bipedal model "breates," make its legs flex a little too, make the arms swing a litte. A model where large sections are mostly static is a bad model.



-------------------------------------------------
GETTING YOUR MILKSHAPE EXPORTED MDL INTO WARCRAFT
-------------------------------------------------
(Using kdub's exporter)


Before doing anything: Find and replace #IND with 0
Now, construct your header - from Sequences, Textures and Materials.
Some people might tell you that sequences are unnecessary (for unanimated doodads etc) but they are WRONG. THERE MUST ALWAYS BE AT LEAST ONE SEQUENCE.
 _ _ _________ _ _
 - - SEQUENCES - -
     

Sequences 1 {
	Anim "Stand" {
		Interval { 41, 2083 },
		Rarity 5,
		NonLooping,
		MinimumExtent { -200, -200, -200 },
		MaximumExtent { 200, 200, 200 },
		BoundsRadius 100,
	}
}

NEW ANIMATIONS: Divide keyframe in Milkshape by 24, then multiply by 1000. Round DOWN - basically, remove the numbers after the point.
THE SEQUENCES MUST COME IN THE ORDER THAT THEY COME IN MILKSHAPE - I.E. Animation from 1 - 25 above animation from 60 - 70 etc

The interval is the period in which the specific animation occurs, start frame followed by end frame. MAKE SURE SEQUENCES DO NOT OVERLAP, OR START ON THE SAME FRAME THAT THE LAST ONE ENDED ON.

Rarity is used for variations of different animations, for example if you have three stand animations and one is longer and thus should not happen so often, increase its Rarity value. This line is entirely optional.

NonLooping means that the animation will not repeat itself - it is crucial for morph, death and attack animations, maybe more. If it does not exist in these animations, the model will constantly cycle, say, the death animation until the unit is removed, even though it is dead and should be decaying; it will be constantly falling over or exploding.

Maximum/Minumum Extent - I actually have no idea what these are used for, but hey. I believe it affects how far off screen the origin must be before the model is removed. This, though, seems to be more affected by the Min/MaxExtents in the header above the sequences.

BoundsRadius is how far your model extends from the origin... It is used to define whether the model is displayed or not at the edge of the screen - for example, if there was no BoundsRadius line, as soon as the origin is off the screen, the whole model disappears, even if its head should still be visible. Also affects selection - the model can be clicked on within its BoundsRadius to select it, but clicking model parts outside will not select it. Again, if there is no BoundsRadius line the model will be unselectable, except by drag selecting. Or it might be the other way around with the Min/Max Extents. Not that it really matters.
 _ _ ______________________ _ _
 - - MATERIALS AND TEXTURES - -
     
NOTE: The following material does not do team-colour: it is a simple way of getting everything working.

Textures 1 {
	Bitmap {
		Image "Textures\RDZMech.blp",
	}
}
Materials 1 {
	Material {
		Layer {
			FilterMode None,
			static TextureID 0,
		}
	}
}

Header with two textures and teamcolour on the main one:

Textures 3 {
	Bitmap {
		Image "",
		ReplaceableId 1,
	}
	Bitmap {
		Image "Textures\RDZMech.blp",
	}
	Bitmap {
		Image "Textures\GenericGlow64.blp",
	}
}
Materials 2 {
	Material {
		Layer {
			FilterMode None,
			Unshaded,
			static TextureID 0,
		}
		Layer {
			FilterMode Blend,
			TwoSided,
			static TextureID 1,
		}
	}
	Material {
		Layer {
			FilterMode Additive,
			Unshaded,
			TwoSided,
			static Alpha 0.5,
			static TextureID 2,
		}
	}
}

The first texture is "ReplaceableId 1," which creates teamcolour depending on the owner.
The second is the model's main skin, which may have an alpha channel which will define where teamcolour shows through.
The third is a glow for some fire, which is actually a soft sphere on black. The "FilterMode Additive" makes this not show a black square with glow in the middle, but the transparent glow itself.
Unshaded makes the geosets with this material unaffected by lighting; they will always display clear and witout shadows.
TwoSided - self explanatory, the skin displays on both sides of the geoset, useful for single-plane weapons etc.
static Alpha - make the material partially transparent. 1 = 100% = solid, 0 = 0% = invisible.

The first material there is a team-colour material. The "top" layer is the team-colour replaceable texture, while the "bottom" layer is a skin with an alpha channel. The alpha channel decides where team colour shows through. This construct is standard for all team-colour, as far as I know.

A NOTE ON REPLACEABLEIDS: These define in-game textures that can change depending on various factors. The main use is for team-coloured areas of a skin (beneath the actual skin via alpha channels) and for coloured hero glows. Also for destructible textures that change depending on tileset/blight etc.

 _ _ ________________ _ _
 - - Portrait Cameras - -
     
Portrait camera: modify position and target for size of model.
(Positions: { X, Y, Z }, Z being height)

Camera "Camera01" {
	Position { 100, 100, 75 },
	FieldOfView 0.785398,
	FarClip 1000,
	NearClip 8,
	Target {
		Position { 0, 0, 50 },
	}
}

It's a bit of a guessing game finding the best coordinates for your camera, but it's just a matter of tweaking to get the right values.

NOTE: Sometimes the in the portrait the model will not appear - if this is happening, try modifying the BoundsRaduius and Min/Max Extents for the portrait sequences, or those in the MDL info section right at the top.

NOTE: Cameras do not require pivot points; their positions are defined wholly by themselves.

--------------------
----Nice Touches----
--------------------

Now that the model is functional, use these nice tips and tricks to add special effects and finishing touches to your model...

____________
GEOSET ANIMS

Making Geosets disappear in animations:

GeosetAnim {
	Alpha 2 {
		DontInterp,
		6250: 1,
		6458: 0,
	}
	static Color { 0, 0.211765, 1 },
	GeosetId 0,
}

0 = invisible, 1 = visible. In between values can be used.
Change "DontInterp" to "Linear" for smooth fade.
AT THE EXACT START FRAME OF EACH SEQUENCE INVOLVED, THE ALPHA MUST BE DEFINED!
If the geosets do odd disappearing acts, make sure that, for example, if it is a fade-out in a death animation that begins at 1530, there is a line in the geosetanim like "1530: 1" or whatever.
static Color - a built-in tint of the geoset, values in the usual BGR format. As shown below, you can also have a changing tint. NOTE - the "static Color" line CANNOT BE USED IN A MATERIAL.

NOTE: Different FilterModes on your materials affect the working of linear GeosetAnims - Additive, Blend work fine, but a teamcolour material will not fade out the model, but fade it into teamcolour. Transparent doesn't work, the model just flashes fitfully occasionally in my experience. I have reason to believe that DontInterp animations work fine with all FilterModes. So be careful.

GeosetAnim {
	Color 2 {
		DontInterp,
		208: { 1, 1, 1 },
		6250: { 1, 1, 1 },
	}
	GeosetId 0,
}
_____________
EVENT OBJECTS

Make "splats", spawn models and sounds play at certain points in the animation:

EventObject "SPNxDNBL" {
	ObjectId 14,
	EventTrack 1 {
		6250,
	}
}

Append these to the end of your MDL and ***add a line to the end PivotPoints list defining the position***, copy off a bone if you're stuck.

War3ObjectData.doc can be found somewhere on the wc3campaigns MDL forums, which details what codes to use to get which effects/sounds...

A NOTE ON PIVOTPOINTS: These are points (well, duh) around the model. Each object in the MDL directly relates to a PivotPoint - ObjectID 0, probably your root bone, will be at the position of the first PivotPoint. ObjectID 1 wil be at the position of the second PivotPoint and so on.

_________________
ATTACHMENT POINTS

Attachment "Origin Ref " {
	ObjectId 47,
}

Make sure this has a corresponding PivotPoint. It can have a "Parent X," line added, to make it follow a bone or something.
Another little trick with the attachment is using it to build in another model - like you would do with spell/item art, but actually hard-wired into the model:

Attachment "Chest Ref" {
	ObjectId 15,
	Parent 5,	// "Mesh07
	Path "FlyingSheep2.MDL",
	Visibility 5 {
		DontInterp,
		667: 1,
		9833: 0,
		13333: 0,
		73000: 0,
		80000: 0,
	}
}

This attachment will add on "FlyingSheep2.mdX" to the model's chest region. FlyingSheep2 itself is actually just the wings with a single stand animation, that of them flapping, and I was using this to test out a method of attaching flapping wings to models without geomerging inanimate ones. Also note the "Visibility" section - this can be used to define if attachments display or not during animations, operating exactly like a GeosetAnim. Good for making your extra bits disappear in the death and decay anims. Not sure if the Attachment model's animations operate in synch with the model; I don't think they would play a death animation when the real model dies etc.
If you make sure that your attachment model only has one animation, you can keep the file-size very low, even if it's been made from an entire unit.
I have reason to believe that attached models appear only at the origin; the origin of the attachment matches the origin of the actual model, although I think the attached model will still move/rotate relative to the attachment point's pivot.
___________________
SCREWING WITH BONES

Fire and/or hero glow:
Create a plane facing forward, square for best results, and make sure each plane has its own bone in the centre, which has no children - if a row is needed for a sword's hero glow, for example, have each bone to be Billboarded the child of a single bone, not children of each other. Or just create the bones whatever way and change the "Parent X," line to the ID of whatever bone you want the "glow" to follow.
Add the line:
	Billboarded,
To the bone. This will make it always face the camera (unless you created the plane facing the wrong direction, in which case the side or something will always face the camera). There are also other version of the Billboard line, for example, that used for the Northrend viney plants that keeps the central stem facing the camera, but not twisting it upwards to follow the camera - i.e. it does not billboard on one axis. However, I am unsure of the code for this and I have had no reason so far to find it out.

Scaling:
Similar to the Rotation and Translation sections that will already exist for each bone, scaling allows the size of geometry attached to the bone to be changed.
	Scaling 3 {
		Linear,
		12083: { 1, 1, 1 },
		12916: { 2.05, 2.05, 2.05 },
		13750: { 1, 1, 1 },
	}
Add this to the bone, and change what keyframes each size is applied in. Scales in { X, Y, Z }. 1 = normal size, 2 = double, 0.5 = half etc. This will cause a smooth translation between scales over the period between keyframes. I have reason to believe that changing "Linear" to "DontInterp" (opposite of what we did with geosetanims) will create an instant change rather than smooth scaling. If problems arise, try setting the scale at the first frame of the sequence, as with the geosetanims. Also remember that scaling is inherited like rotation and translation - if you scale the root bone to 10 and the pelvis to 10, then the pelvis will actually be 100 times the size, or something like that. If it's causing problems, just change the "Parent X," line to another objectID.
________________
GLOBAL SEQUENCES

Global sequences can be used to make the motion of a bone or an animated texture loop continuously throughout the use of the model, no matter what animation is playing.

GlobalSequences 2 {
	Duration 2833,
	Duration 664,
}

To refer to a global sequnce, simple add this line above your list of keyframes:
			GlobalSeqId 0,
Global sequences can be used on anything, as far as I know.
_________________________________
TVERTEXANIMS - ADVANCED MATERIALS

TVertexAnims can be used to create the effect of a material panning in a certain direction over the model.

TextureAnims 1 {
	TVertexAnim {
		Translation 2 {
			Linear,
			GlobalSeqId 0,
			0: { 0, 0, 0 },
			2833: { 0, 1, 0 },
		}
	}
}

This will simply cause the texture to move 'forward' (I've not worked out directions yet) once over 2833, bringing the image back to its 'start'. The distance is relative to the image size; 1 makes it move the length of itself, 1.5 would make it go faster by moving the image one and a half times its length etc.
In this section, the GlobalSeqId is commonly used, but it is not necessary - if you require more precise control of the texture, then a list of keyframes exactly like that of a bone may be used, being activated in exactly the same manner.

NOTE - You can also use scaling on TVertexAnims. From this, I can also speculate that rotation will work.

NOTE - The third value, which would be "Z" in a bone's rotation/translation/scaling seems to have no effect for animating textures.

Finally, you must add a reference to this in the Material that will use it:
			TVertexAnimId 0,
The Id is counted in the same manner as everywhere else.
You will also need to add these lines to the Texture that is being animated:
		WrapWidth,
		WrapHeight,
This will make the texture pan nicely, whereas a texture lacking these 'stretches' the edges until the mesh shows a set of lines of the edge line of pixels, until it starts the animation again.

Of course, you can always fall back on a device which constantly switches the texture between each texture in the list; like this one from the Water Elemental, which produces a nice watery effect... (You'll need to remove the "static TextureID" line in favour of this section)
			TextureID 8 {
				DontInterp,
				GlobalSeqId 0,
				0: 0,
				83: 1,
				166: 2,
				249: 3,
				332: 4,
				415: 5,
				498: 6,
				581: 7,
			}
This can be coupled with any TVertexAnim or other material devices; it is just another block you can insert.